/**
 * Organization:  SimVentions, Inc.
 * Creation Date: Jul 22, 2011
 */
package org.omg.tacsit.worldwind.ui.geometry;

import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.InternationalFormatter;
import org.omg.tacsit.ui.geometry.PositionPanel;
import org.omg.tacsit.geometry.GeodeticPosition;
import org.omg.tacsit.common.text.DecimalDegreeFormat;
import org.omg.tacsit.common.ui.ComponentUtils;
import org.omg.tacsit.worldwind.geometry.WWGeodeticPosition;
import org.omg.tacsit.worldwind.geometry.WWSurfaceRectangle;

/**
 * A panel that displays and edits a WWSurfaceRectangle.
 * @author Matthew Child
 */
public class WWSurfaceRectanglePanel extends javax.swing.JPanel
{

  private WWSurfaceRectangle value;
  
  private boolean editable;
  
  private boolean isInitializingFieldValues;

  /**
   * Creates a new instance.
   */
  public WWSurfaceRectanglePanel()
  {
    editable = true;
    isInitializingFieldValues = false;
    initComponents();
  }

  /**
   * Get the value being displayed.
   * @return The value being displayed.
   */
  public WWSurfaceRectangle getValue()
  {
    return value;
  }

  /**
   * Sets the value being displayed.
   * @param value The value being displayed.
   */
  public void setValue(WWSurfaceRectangle value)
  {
    this.value = value;
    
    updateFieldValues(this.value);
    
    checkEditState();
  }
  
  
  private void updateFieldValues(WWSurfaceRectangle rectangle)
  {
    isInitializingFieldValues = true;
    
    org.omg.tacsit.common.math.Angle angle = org.omg.tacsit.common.math.Angle.ZERO;
    double widthMeters = 0.0d;
    double heightMeters = 0.0d;
    GeodeticPosition centerPoint = null;

    if (rectangle != null)
    {
      angle = org.omg.tacsit.common.math.Angle.fromRadians(rectangle.getOrientation());
      widthMeters = rectangle.getWidth();
      heightMeters = rectangle.getHeight();
      centerPoint = rectangle.getCenter();
    }
    
    angleField.setValue(angle);
    widthField.setValue(widthMeters);
    heightField.setValue(heightMeters);
    centerPointPanel.setValue(centerPoint);
    
    isInitializingFieldValues = false;
  }
  
  /**
   * Sets whether or not the value in the panel can be edited.
   * @param editable whether the value can be edited.
   */
  public void setEditable(boolean editable)
  {
    this.editable = editable;
    checkEditState();
  }

  private void checkEditState()
  {
    boolean propertiesEditable = arePropertiesEditable();

    widthField.setEditable(propertiesEditable);
    heightField.setEditable(propertiesEditable);
    centerPointPanel.setEditable(propertiesEditable);
    angleField.setEditable(propertiesEditable);
  }

  private boolean arePropertiesEditable()
  {
    return editable && (value != null);
  }
  
  private void setWidth(double width)
  {
    if (arePropertiesEditable())
    {
      this.value.setWidth(width);
    }
  }
  
  private void setHeight(double height)
  {
    if (arePropertiesEditable())
    {
      this.value.setHeight(height);
    }
  }
  
  private void setAngle(org.omg.tacsit.common.math.Angle angle)
  {
    if (arePropertiesEditable())
    {
      gov.nasa.worldwind.geom.Angle wwAngle = gov.nasa.worldwind.geom.Angle.fromRadians(angle.getRadians());
      this.value.setOrientation(wwAngle);
    }
  }

  private void setCenterPoint(GeodeticPosition centerPoint)
  {
    if (arePropertiesEditable())
    {
      WWGeodeticPosition center = WWGeodeticPosition.toWWGeodeticPosition(centerPoint);
      this.value.setCenter(center);
    }
  }
  
  private double getDoubleValue(Number number)
  {
    double doubleValue = 0.0;
    if(number != null)
    {
      doubleValue = number.doubleValue();
    }
    return doubleValue;
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
    javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
    widthField = new javax.swing.JFormattedTextField();
    heightField = new javax.swing.JFormattedTextField();
    javax.swing.JLabel jLabel3 = new javax.swing.JLabel();
    angleField = new javax.swing.JFormattedTextField();
    javax.swing.JLabel jLabel4 = new javax.swing.JLabel();
    javax.swing.JLabel jLabel5 = new javax.swing.JLabel();
    javax.swing.JLabel jLabel6 = new javax.swing.JLabel();
    centerPointPanel = new org.omg.tacsit.ui.geometry.PositionPanel();

    FormListener formListener = new FormListener();

    jLabel1.setText("Width:");

    jLabel2.setText("Height:");

    widthField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter()));
    widthField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
    widthField.addPropertyChangeListener(formListener);

    heightField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter()));
    heightField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
    heightField.addPropertyChangeListener(formListener);

    jLabel3.setText("Angle:");

    angleField.setFormatterFactory(new DefaultFormatterFactory(new InternationalFormatter(new DecimalDegreeFormat())));
    angleField.setHorizontalAlignment(javax.swing.JTextField.TRAILING);
    angleField.addPropertyChangeListener(formListener);

    jLabel4.setText("Meters");

    jLabel5.setText("Meters");

    jLabel6.setText("Degrees (From North)");

    centerPointPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("CenterPoint"));
    centerPointPanel.addPropertyChangeListener(formListener);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jLabel1)
              .addComponent(jLabel2)
              .addComponent(jLabel3))
            .addGap(34, 34, 34)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                  .addComponent(widthField)
                  .addComponent(heightField, javax.swing.GroupLayout.PREFERRED_SIZE, 96, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addComponent(jLabel4)
                  .addComponent(jLabel5)))
              .addGroup(layout.createSequentialGroup()
                .addComponent(angleField, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel6))))
          .addComponent(centerPointPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel1)
          .addComponent(widthField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel4))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel2)
          .addComponent(heightField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel5))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel3)
          .addComponent(angleField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel6))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(centerPointPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
  }

  // Code for dispatching events from components to event handlers.

  private class FormListener implements java.beans.PropertyChangeListener {
    FormListener() {}
    public void propertyChange(java.beans.PropertyChangeEvent evt) {
      if (evt.getSource() == widthField) {
        WWSurfaceRectanglePanel.this.widthPropertyChange(evt);
      }
      else if (evt.getSource() == heightField) {
        WWSurfaceRectanglePanel.this.heightPropertyChange(evt);
      }
      else if (evt.getSource() == angleField) {
        WWSurfaceRectanglePanel.this.anglePropertyChange(evt);
      }
      else if (evt.getSource() == centerPointPanel) {
        WWSurfaceRectanglePanel.this.centerPropertyChange(evt);
      }
    }
  }// </editor-fold>//GEN-END:initComponents

  private void widthPropertyChange(java.beans.PropertyChangeEvent evt)//GEN-FIRST:event_widthPropertyChange
  {//GEN-HEADEREND:event_widthPropertyChange
    if(!isInitializingFieldValues)
    {
      String propertyName = evt.getPropertyName();
      if (ComponentUtils.FORMATTED_FIELD_VALUE_PROPERTY.equals(propertyName))
      {
        Number width = (Number) widthField.getValue();
        setWidth(getDoubleValue(width));
      }
    }
  }//GEN-LAST:event_widthPropertyChange

  private void heightPropertyChange(java.beans.PropertyChangeEvent evt)//GEN-FIRST:event_heightPropertyChange
  {//GEN-HEADEREND:event_heightPropertyChange
    if(!isInitializingFieldValues)
    {
      String propertyName = evt.getPropertyName();
      if (ComponentUtils.FORMATTED_FIELD_VALUE_PROPERTY.equals(propertyName))
      {
        Number height = (Number) heightField.getValue();
        setHeight(getDoubleValue(height));
      }
    }
  }//GEN-LAST:event_heightPropertyChange

  private void anglePropertyChange(java.beans.PropertyChangeEvent evt)//GEN-FIRST:event_anglePropertyChange
  {//GEN-HEADEREND:event_anglePropertyChange
    if(!isInitializingFieldValues)
    {
      String propertyName = evt.getPropertyName();
      if (ComponentUtils.FORMATTED_FIELD_VALUE_PROPERTY.equals(propertyName))
      {
        org.omg.tacsit.common.math.Angle angle = (org.omg.tacsit.common.math.Angle) angleField.getValue();
        setAngle(angle);
      }
    }
  }//GEN-LAST:event_anglePropertyChange

  private void centerPropertyChange(java.beans.PropertyChangeEvent evt)//GEN-FIRST:event_centerPropertyChange
  {//GEN-HEADEREND:event_centerPropertyChange
    if (!isInitializingFieldValues)
    {
      String propertyName = evt.getPropertyName();
      if (propertyName.equals(PositionPanel.VALUE_PROPERTY))
      {
        GeodeticPosition position = centerPointPanel.getValue();
        setCenterPoint(position);
      }
    }
  }//GEN-LAST:event_centerPropertyChange
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JFormattedTextField angleField;
  private org.omg.tacsit.ui.geometry.PositionPanel centerPointPanel;
  private javax.swing.JFormattedTextField heightField;
  private javax.swing.JFormattedTextField widthField;
  // End of variables declaration//GEN-END:variables
}
